﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ASelect
{
    /// <summary>
    /// The ASelectData class emulates the data layer of A-Select and fetches
    /// data from the database.
    /// </summary>
    public class ASelectData
    {
        /// <summary>
        /// The LoginState enumeration defines the possible return
        /// values when an entity tries to log in.
        /// </summary>
        public enum LoginState
        {
            SUCCESSFUL = 1,
            USERNAME_ERROR = 2,
            PASSWORD_ERROR = 3,
            USERNAME_EMPTY = 4,
            PASSWORD_EMPTY = 5
        };

        /// <summary>
        /// Default constructor.
        /// </summary>
        public ASelectData()
        {

        }

        /// <summary>
        /// Check a student or teacher number and password hash and return
        /// a login state.
        /// </summary>
        /// <param name="number">The number to check</param>
        /// <param name="passwordHash">The hash to check</param>
        /// <returns>A LoginState value</returns>
        public LoginState Login(string number, string passwordHash)
        {
            /* define default result */
            LoginState result = LoginState.USERNAME_ERROR;
            
            /* if the number is not empty */
            if (number != null && number.Length > 0)
            {
                /* if the password is not empty */
                if (passwordHash != null && passwordHash.Length > 0)
                {
                    /* create data context */
                    ASelectDataContext database = new ASelectDataContext();

                    /* create query */
                    IEnumerable<Account> foundAccounts =
                        from account in database.Accounts
                        where account.Number == number
                        select account;

                    /* if an Account was found */
                    if (foundAccounts.Count() > 0)
                    {
                        /* get the first Account */
                        Account found = foundAccounts.First();

                        /* if the password equals the hash */
                        if (found.Password.Equals(passwordHash))
                        {
                            /* logged in successfully */
                            result = LoginState.SUCCESSFUL;

                            /* update last login time */
                            found.LastLogin = DateTime.Now;

                            /* save changes */
                            database.SubmitChanges();
                        }
                        else
                        {
                            /* fill in correct error code */
                            result = LoginState.PASSWORD_ERROR;
                        }
                    }
                    else
                    {
                        /* fill in correct error code */
                        result = LoginState.USERNAME_ERROR;
                    }
                }
                else
                {
                    /* fill in correct error code */
                    result = LoginState.PASSWORD_EMPTY;
                }
            }
            else
            {
                /* fill in correct error code */
                result = LoginState.USERNAME_EMPTY;
            }

            /* return the result */
            return result;
        }

        /// <summary>
        /// Return the Account with the given number.
        /// </summary>
        /// <param name="number">The account's number</param>
        /// <returns>An Account object</returns>
        public Account GetAccount(string number)
        {
            /* define default result */
            Account result = null;

            /* if the number is not empty */
            if (number != null && number.Length > 0)
            {
                /* create data context */
                ASelectDataContext database = new ASelectDataContext();

                /* create query */
                IEnumerable<Account> foundAccounts =
                    from account in database.Accounts
                    where account.Number == number
                    select account;

                /* if an Account was found */
                if (foundAccounts.Count() > 0)
                {
                    /* get the first Account */
                    result = foundAccounts.First(); 
                }
            }

            /* return the result */
            return result;
        }
    }
}
